using System;
using System.Collections.Generic;
using System.Text;

namespace DatabaseCode
{
  class SrcMaker
  {
    //RelationShipクラス
    //  bool CanAdd(const DataMgr* data_mgr, const MgrDataMgr* mgr_data_mgr, 
    //              const TableType table_type, const void* data);
    //  bool CanRemove(const DataMgr* data_mgr, const MgrDataMgr* mgr_data_mgr, 
    //                  const TableType table_type, const void* data);
    public static string OutRelationship(D1_Headers headers)
    {
      StringBuilder addString = new StringBuilder();
      StringBuilder removeString = new StringBuilder();
      string managerName;
      string memberClass;
      string memberHeader;
      string tableName;
      //string refClass;
      //string refMember;
      //string refHeader;
      References refs;
//      List<Reference1>.Enumerator references;
//      Reference1 ref1;

      //データヘッダの列挙(mgr_data.hなどの構造体部分)
      foreach(D2_Header header in headers.Headers)
      {
        managerName = header.ManagerMemberName; // マネージャ名（例：mgr_data_mgr）
        //テーブル（構造体）の列挙
        foreach(D3_Table table in header.Tables)
        {
          tableName = Utility.MemberStringWithS_(table.Tablename); // テーブル名（例：item_kinds_）
          // CanAddの例
          //case Enums::kTableItem:
          //  for (i = 0; i < mgr_data_mgr->item_kinds_.table.size(); i++)
          //  {
          //    if (IsEqual(mgr_data_mgr->item_kinds_.table[i].code, ((Item*)data)->item_kind_code))
          //      break;
          //  }
          //  if (i == mgr_data_mgr->item_kinds_.table.size()) return false;
          //  break;
          addString.Append("  case Enums::kTable" + table.Tablename + ":\r\n");
          foreach (D4_Field field in table.Fields)
          {
            if (field.HasReference)
            {
              //headers.FindReference(datatype.refClass, datatype.refMember, 
              //  out refHeader, out refClass, out refMember);
              //refClass = Utility.MemberStringWithS_(refClass);
              memberHeader = Utility.SeparateByUndercores(headers.GetHeaderName(field.RefTable));
              memberClass = Utility.MemberStringWithS_(field.RefTable);
              addString.Append("    for (i = 0; i < " + memberHeader +
                "->" + memberClass + ".table.size(); i++)\r\n");
              addString.Append("    {\r\n");
              addString.Append("      if (IsEqual(" + memberHeader + "->" +
                memberClass + ".table[i]." + field.RefMember + ", ((" +
                table.Tablename + "*)data)->" + field.Variablename + "))\r\n");
              addString.Append("      break;\r\n");
              addString.Append("    }\r\n");
              addString.Append("    if (i == " + memberHeader + "->" + field.RefTable + ".table.size()) return false;\r\n");
            }
          }
          addString.Append("    break;\r\n");

          // Removeの例
          //  case Enums::kTableItemKind:
          //    for (int i = 0; i < mgr_data_mgr->items_.table.size(); i++)
          //    {
          //      if (IsEqual(mgr_data_mgr->items_.At(i).item_kind_code,
          //                   ((ItemKind*)data)->code))
          //        return false;
          //    }
          //    break;
          removeString.Append("  case Enums::kTable" + table.Tablename + ":\r\n");
          foreach (D4_Field field in table.Fields)
          {
            if (headers.FindReference(table.Tablename, field.Variablename, out refs))
            {
              Debug.AddTempMessageLine("remove参照あった。 " + table.Tablename + "." + field.Variablename + 
                "  " + refs.refs.Count + "件");
              foreach (Reference1 ref1 in refs.refs)
              {
                removeString.Append("    for (int i = 0; i < " + ref1.headername + "->" + ref1.tablename + 
                  ".table.size(); i++)\r\n");
                removeString.Append("    {\r\n");
                removeString.Append("      if (IsEqual(" + ref1.headername + "->" + ref1.tablename + 
                  ".At(i)." + ref1.membername + ",");
                removeString.Append("                   ((" + tableName + "*)data)->" +
                  field.Variablename + "))\r\n");
                removeString.Append("        return false;\r\n");
                removeString.Append("    }\r\n");
              }
            }
          }
          removeString.Append("    break;\r\n");
        }
      }

      return @"//戻り値：参照に必要なデータがない場合は false を返す。
bool RelationShip::CanAdd
  (" + headers.GetManagerParameterString() + @", 
   const Enums::Table table_type, const void* data)
{
  int i;

  switch(table_type)
  {
" + addString.ToString() + @"
  }
  return true;
}

//戻り値：他のデータによって参照されている場合は false を返す。
bool RelationShip::CanRemove
  (" + headers.GetManagerParameterString() + @", 
   const Enums::Table table_type, const void* data)
{
  int i;

  switch(table_type)
  {
" + removeString.ToString() + @"
  }
  return true;
}";
    }  // public static string OutRelationShip(List<TableDesign> inputData, StructHeaders headers)
  }
}
